package com.yoki.cloud.common.utils.aop.security;



import com.yoki.cloud.common.utils.aop.security.annotation.EnablePrivacyDisplay;
import com.yoki.cloud.common.utils.aop.security.annotation.PrivacyDisplay;
import com.yoki.cloud.common.utils.aop.security.enums.PrivacyDisplayType;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Objects;

public class PrivacyDisplayUtils {

    static final int IDDEN_LENGTH = 10;

    static final String DEFAULT_REGULAR = "([\\d\\D]{1})(.*)";

    static final String DEFAULT_REPLACEMENT = "$1**";

    public static void privacyDisplay(Object bean) throws IllegalAccessException {
        //判断对象是否有注解
        if (!PrivacyDisplayAnnoUtils.isNeedPrivacyDisplayClass(bean)) {
            return;
        }
        //获取类
        Class<?> clazz = bean.getClass();
        //获取字段
        Field[] fields = clazz.getDeclaredFields();
        if (null != fields && fields.length != 0) {
            int length = fields.length;
            for (int i = 0; i < length; i++) {
                Field field = fields[i];
                privacyDisplay(bean, field);
            }
        }
    }

    public static void privacyDisplay(Object bean, Field field) throws IllegalAccessException {
        //判断对象是否有注解
        if (!PrivacyDisplayAnnoUtils.isNeedPrivacyDisplayClass(bean)) {
            return;
        }
        //判断字段是否有注解
        if (!PrivacyDisplayAnnoUtils.isNeedPrivacyDisplayField(field)) {
            return;
        }
        //判断字段是否为String类型
        if (field.getType() == String.class) {
            String value = (String) field.get(bean);
            //设置非public的可访问
            field.setAccessible(true);
            PrivacyDisplay anno = field.getAnnotation(PrivacyDisplay.class);
            String privacyValue = privacy(anno, value);
            field.set(bean, privacyValue);
        }
    }

    private static String privacy(PrivacyDisplay anno, String value) {
        if (null == value || "".equals(value)) {
            return null;
        }
        PrivacyDisplayType type = anno.type();
        if (PrivacyDisplayType.NON_PRIVACY_DISPLAY == type) {
            return value;
        }
        String regular = anno.regular();
        String replacement = anno.replacement();
        if (null != regular && null != replacement
                && !"".equals(regular) && !"".equals(replacement)) {
            return value.replaceAll(regular, replacement);
        }
        StringBuffer valueBuf = new StringBuffer();
        switch (type) {
            case NAME:
                valueBuf.append(value.substring(0, 1));
                valueBuf.append(value.substring(1, value.length()).replaceAll(".", "*"));
                break;
            case IDDEN:
                if (value.length() > IDDEN_LENGTH) {
                    valueBuf.append(value.toUpperCase().replaceAll("(\\d{4})\\d{10}([0-9X]{4})", "$1********$2"));
                } else {
                    valueBuf.append(value.replaceAll("(\\d)", "*"));
                }
                break;
            case PHONE:
                valueBuf.append(value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
                break;
            case DEFAULT:
                valueBuf.append(value.replaceAll(DEFAULT_REGULAR, DEFAULT_REPLACEMENT));
                break;
            case NON_PRIVACY_DISPLAY:
                break;
        }
        return valueBuf.toString();
    }


}
